class_name RoomSpecialTileMapLayerReplacer

## 默认基点是左上角
## 支持多个物体，物体内部可能是随机的，物体的原点不一定在哪，一个tilemap支持多种替换tile
## 需要替换的Tile：需要加个CustomTileData -> ReplaceTile:int，0会是默认值，不要用

#region 属性
var room:BaseRoom
var tile_map_layer:TileMapLayer
var coords_dict:Dictionary = {}
var replace_tile_ids:Dictionary = {}
var cant_remove_coords_dict:Dictionary = {}
#endregion
#region 字段
#endregion
#region 信号
#endregion

#region 基类方法
#endregion
#region 公共方法
func init(room:BaseRoom,tile_map_layer:TileMapLayer):
	self.room = room
	self.tile_map_layer = tile_map_layer
	self.coords_dict.clear()
	self.replace_tile_ids.clear()
	self.cant_remove_coords_dict.clear()
	for coords in tile_map_layer.get_used_cells().filter(func(coords): 
		var id = tile_map_layer.get_cell_tile_data(coords).get_custom_data(Constant.REPLACE_TILE_LAYER_NAME)
		return id != null and id != 0
		):
		coords_dict[coords] = true
		var id = tile_map_layer.get_cell_tile_data(coords).get_custom_data(Constant.REPLACE_TILE_LAYER_NAME)
		if not replace_tile_ids.has(id):
			replace_tile_ids.set(id,true)
func get_count(info:RoomSpecialLayerInfo) -> int:
	if info.count_range.y < 0:
		return -1
	var count = GameManager.get_grng().grng_randi_range(info.count_range.x,info.count_range.y)
	return count
func get_matrix(info:RoomSpecialLayerInfo,left_top_coords:Vector2i,shape:Vector2i,result_dict:Dictionary) -> Array[Array]:
	var matrix:Array[Array] = []
	for row in range(shape.x):
		matrix.append([])
		for col in range(shape.y):
			var coords = Vector2i(left_top_coords.x + col,left_top_coords.y + row)
			var tile_data = tile_map_layer.get_cell_tile_data(coords)
			if not tile_data:
				continue
			var replace_tile_id = tile_data.get_custom_data(Constant.REPLACE_TILE_LAYER_NAME)
			if replace_tile_id and info.replace_room_tile_info.special_replae_id == replace_tile_id and coords_dict.get(coords,false):
				matrix[row].append(true)
				result_dict.set(coords,true)
			else:
				matrix[row].append(false)
	return matrix
func replace_scene(info:RoomSpecialLayerInfo,scene_info:RoomSceneInfo,coords_dict:Dictionary) -> Node2D:
	## 创建Scene，并设置父对象
	var scene = Utils.random_get_count(scene_info.scenes,1,false,GameManager.get_grng())
	if scene.size() > 0:
		scene = scene[0]
	else:
		return null
	var item = scene.instantiate()
	room.add_child(item)
	## 移动位置
	var pos = tile_map_layer.to_global(tile_map_layer.map_to_local(coords_dict.keys()[0]) - Vector2(tile_map_layer.tile_set.tile_size)/2) + scene_info.get_anchor_point_pos(Vector2(tile_map_layer.tile_set.tile_size))
	item.global_position = pos
	return item
func replace_tile(info:RoomSpecialLayerInfo,coords:Vector2i):
	## 放置Tile
	var tile_info = Utils.random_get_count(info.room_tile_infos,1,false,GameManager.get_grng())
	if tile_info.size() > 0:
		tile_info = tile_info[0]
	else:
		return
	tile_map_layer.set_cell(coords,tile_info.source_id,tile_info.atlas_coords,tile_info.alternative_tile)
func replace(info:RoomSpecialLayerInfo) -> Array[Node2D]:
	var items:Array[Node2D] = []
	var used_coords = tile_map_layer.get_used_cells().filter(func(coords): 
		var id = tile_map_layer.get_cell_tile_data(coords).get_custom_data(Constant.REPLACE_TILE_LAYER_NAME)
		return id != null and id == info.replace_room_tile_info.special_replae_id)
	if info.is_random:
		Utils.shuffle(used_coords,GameManager.get_grng())
	var count = get_count(info)
	for coords in used_coords:
		if count == 0:
			break
		if not coords_dict.has(coords):
			continue
		if info.replace_type == RoomSpecialLayerInfo.ReplaceType.Scene:
			var result_dict = {}
			var scene_info = Utils.random_get_count(info.room_scene_infos,1,false,GameManager.get_grng())
			if scene_info.size() > 0:
				scene_info = scene_info[0]
			else:
				continue
			var matrix = get_matrix(info,coords,scene_info.pattern_matrix.get_shape(),result_dict)
			if scene_info.pattern_matrix.check_pattern(matrix,func(x):return x):
				for c in result_dict.keys():
					coords_dict.erase(c)
				count -= 1
			items.append(replace_scene(info,scene_info,result_dict))
		elif info.replace_type == RoomSpecialLayerInfo.ReplaceType.Tile:
			coords_dict.erase(coords)
			cant_remove_coords_dict.set(coords,true)
			count -= 1
			replace_tile(info,coords)
	return items
func replace_all() -> Array[Node2D]:
	var items:Array[Node2D] = []
	for id in replace_tile_ids.keys():
		var info = room.get_room_special_layer_info_by_replace_tile_id(id)
		if info and info.enable:
			items.append_array(replace(info))
	## 清空所有的特殊Tile
	for coords in tile_map_layer.get_used_cells().filter(func(coords): 
		var id = tile_map_layer.get_cell_tile_data(coords).get_custom_data(Constant.REPLACE_TILE_LAYER_NAME)
		return id != null and id != 0 and not cant_remove_coords_dict.has(coords)
		):
		tile_map_layer.erase_cell(coords)
	return items
#endregion
#region 私有方法
#endregion
#region 生命周期函数
#endregion
